﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace CPPEI.Coolzon.UI.DataPartLib
{
    /// <summary>
    /// visifire仪表盘组件的父类
    /// </summary>
    public abstract class PartVisifireGauge : DataPart
    {
        #region XProperties

        /// <summary>
        /// 仪表盘最小值
        /// </summary>
        [XProperty(XPropertyCategory.Other, "Minimum", "最小值")]
        public double? XMinimum
        {
            get
            {
                return (double)GetValue(MinimumProperty);
            }
            set
            {
                SetValue(MinimumProperty, value);
            }
        }

        /// <summary>
        /// 仪表盘最大值
        /// </summary>
        [XProperty(XPropertyCategory.Other, "Maximum", "最大值")]
        public double? XMaximum
        {
            get
            {
                return (double)GetValue(MaximumProperty);
            }
            set
            {
                SetValue(MaximumProperty, value);
            }
        }

        /// <summary>
        /// 仪表盘步长
        /// </summary>
        [XProperty(XPropertyCategory.Other, "Interval", "步长")]
        public double? Xinterval
        {
            get
            {
                return (double)GetValue(IntervalProperty);
            }
            set
            {
                SetValue(IntervalProperty, value);
            }
        }

        /// <summary>
        /// 仪表盘阈值
        /// </summary>
        [XProperty(XPropertyCategory.Other, "Threshold", "阈值")]
        public double? XThreshold
        {
            get
            {
                return (double)GetValue(ThresholdProperty);
            }
            set
            {
                SetValue(ThresholdProperty, value);
            }
        }

        /// <summary>
        /// 仪表盘显示阈值
        /// </summary>
        [XProperty(XPropertyCategory.Other, "IsShowThreshold", "显示阈值")]
        public bool? XIsShowThreshold
        {
            get
            {
                return (bool)GetValue(IsShowThresholdProperty);
            }
            set
            {
                SetValue(IsShowThresholdProperty, value);
            }
        }

        /// <summary>
        /// 仪表盘颜色范围
        /// </summary>
        [XProperty(XPropertyCategory.Other, "DataRanges", "范围")]
        public List<DataRange> XDataRanges
        {
            get
            {
                return (List<DataRange>)GetValue(DataRangesProperty);
            }
            set
            {
                SetValue(DataRangesProperty, value);
            }
        }

        /// <summary>
        /// 显示仪表盘刻度
        /// </summary>
        [XProperty(XPropertyCategory.Other, "IsScaleVisible", "显示刻度")]
        public bool? XIsScaleVisible
        {
            get
            {
                return (bool)GetValue(IsScaleVisibleProperty);
            }
            set
            {
                SetValue(IsScaleVisibleProperty, value);
            }
        }

        /// <summary>
        /// 填充区域背景色
        /// </summary>
        [XProperty(XPropertyCategory.Other, "FillBarBackground", "填充区域背景色")]
        public Brush XFillBarBackground
        {
            get
            {
                return (Brush)GetValue(FillBarBackgroundProperty);
            }
            set
            {
                SetValue(FillBarBackgroundProperty, value);
            }
        }

        /// <summary>
        /// 填充区域边框颜色
        /// </summary>
        [XProperty(XPropertyCategory.Other, "FillBarBorderBrush", "填充区域边框颜色")]
        public Brush XFillBarBorderBrush
        {
            get
            {
                return (Brush)GetValue(FillBarBorderBrushProperty);
            }
            set
            {
                SetValue(FillBarBorderBrushProperty, value);
            }
        }

        /// <summary>
        /// 填充区域边框厚度
        /// </summary>
        [XProperty(XPropertyCategory.Other, "FillBarBorderThickness", "填充区域边框厚度")]
        public Thickness XFillBarBorderThickness
        {
            get
            {
                return (Thickness)GetValue(FillBarBorderThicknessProperty);
            }
            set
            {
                SetValue(FillBarBorderThicknessProperty, value);
            }
        }

        [XProperty(XPropertyCategory.Other, "ScaleLabelPosition", "刻度显示位置")]
        public string XScaleLabelPosition
        {

            get
            {
                return (string)GetValue(ScaleLabelPositionProperty);
            }
            set
            {
                SetValue(ScaleLabelPositionProperty, value);
            }
        }

        [XProperty(XPropertyCategory.Other, "ScaleFontSize", "刻度字体大小")]
        public double? XScaleFontSize
        {
            get
            {
               return (double) GetValue(ScaleFontSizeProperty);
            }
            set
            {
                SetValue(ScaleFontSizeProperty, value);
            }
        }

        #endregion

        #region Dependency properties

        /// <summary>
        /// Dependency property to Get/Set the Minimum 
        /// </summary>
        public static DependencyProperty MinimumProperty =
            DependencyProperty.Register("XMinimum", typeof(double), typeof(PartVisifireGauge),
            null);

    
        /// <summary>
        /// Dependency property to Get/Set the Maximum 
        /// </summary>
        public static DependencyProperty MaximumProperty =
            DependencyProperty.Register("XMaximum", typeof(double), typeof(PartVisifireGauge), 
            null);

        /// <summary>
        /// Dependency property to Get/Set the Maximum 
        /// </summary>
        public static DependencyProperty IntervalProperty =
            DependencyProperty.Register("XInterval", typeof(double), typeof(PartVisifireGauge),
            null);

        /// <summary>
        /// Dependency property to Get/Set the Threshold 
        /// </summary>
        public static DependencyProperty ThresholdProperty =
            DependencyProperty.Register("XThreshold", typeof(double), typeof(PartVisifireGauge),
            null);

      
        /// <summary>
        /// Dependency property to Get/Set the IsShowThreshold 
        /// </summary>
        public static DependencyProperty IsShowThresholdProperty =
            DependencyProperty.Register("XIsShowThreshold", typeof(bool), typeof(PartVisifireGauge),
            null);

        /// <summary>
        /// Dependency property to Get/Set the DataRanges 
        /// </summary>
        public static DependencyProperty DataRangesProperty =
            DependencyProperty.Register("XDataRanges", typeof(List<DataRange>), typeof(PartVisifireGauge),
            null);

        /// <summary>
        /// Dependency property to Get/Set the Scale Visible
        /// </summary>
        public static DependencyProperty IsScaleVisibleProperty =
            DependencyProperty.Register("XIsScaleVisible", typeof(bool), typeof(PartVisifireGauge),
            null);

        /// <summary>
        /// Dependency property to Get/Set the FillBarBackground
        /// </summary>
        public static DependencyProperty FillBarBackgroundProperty =
            DependencyProperty.Register("XFillBarBackground", typeof(Brush), typeof(PartVisifireGauge),
            null);
 
        /// <summary>
        /// Dependency property to Get/Set the FillBarBorderBrush
        /// </summary>
        public static DependencyProperty FillBarBorderBrushProperty =
            DependencyProperty.Register("XFillBarBorderBrush", typeof(Brush), typeof(PartVisifireGauge),
            null);

        /// <summary>
        /// Dependency property to Get/Set the FillBarBorderThickness
        /// </summary>
        public static DependencyProperty FillBarBorderThicknessProperty =
            DependencyProperty.Register("XFillBarBorderThickness", typeof(Thickness), typeof(PartVisifireGauge),
            null);

        /// <summary>
        /// Dependency property to Get/Set the ScaleLabelPosition 
        /// </summary>
        public static readonly DependencyProperty ScaleLabelPositionProperty =
            DependencyProperty.Register("XScaleLabelPosition", typeof(string), typeof(PartVisifireGauge), 
            null);

        /// <summary>
        /// Dependency property to Get/Set the ScaleFontSize 
        /// </summary>
        public static readonly DependencyProperty ScaleFontSizeProperty =
            DependencyProperty.Register("XScaleFontSize", typeof(double), typeof(PartVisifireGauge),
            null);
       
        #endregion

        #region Constructor

        public PartVisifireGauge()
        {
            Xinterval = 25;
            XMinimum = 0;
            XMaximum = 125;
            XIsScaleVisible = true;
            XIsShowThreshold = false;
            XScaleFontSize = 12;
        }

        protected override void OnInit(PartContext context)
        {
            base.OnInit(context);

            Visifire.Gauges.Gauge gauge = GetVisifireGauge();

            gauge.Background = new SolidColorBrush(Colors.Transparent);
            gauge.OuterBackground = new SolidColorBrush(Colors.Transparent);

            //将AnimationEnabled置为false，在绑定数据时手动添加动画
            gauge.AnimationEnabled = false;
            gauge.CircularScales.Clear();
            gauge.Ranges.Clear();
            gauge.Indicators.Clear();

            // 添加区域
            if (XDataRanges != null && XDataRanges.Count > 0)
            {
                foreach (DataRange dataRange in XDataRanges)
                {
                    Visifire.Gauges.Range range = new Visifire.Gauges.Range();
                    range.StartValue = dataRange.StartValue;
                    range.EndValue = dataRange.EndValue;
                    range.StartWidth = dataRange.StartWidth;
                    range.EndWidth = dataRange.EndWidth;
                    range.Background = dataRange.Background.Brush;
                    range.BorderBrush = dataRange.BorderBrush.Brush;
                    range.BorderThickness = dataRange.BorderThickness;
                    range.Placement = Visifire.Gauges.PlacementTypes.Center;
                    gauge.Ranges.Add(range);
                }
            }
        }

        public void InitControl(Visifire.Gauges.Gauge ctlGauge)
        {
            if (ctlGauge.Type == Visifire.Gauges.GaugeTypes.Linear)
            {
                if (ctlGauge.LinearScales != null && ctlGauge.LinearScales.Count > 0)
                {
                    if (!(bool)XIsScaleVisible)
                    {
                        Visifire.Gauges.ScaleLabels scaleLabels = new Visifire.Gauges.ScaleLabels();
                        scaleLabels.Visibility = System.Windows.Visibility.Hidden;
                        ctlGauge.LinearScales[0].ScaleLabels = scaleLabels;

                        Visifire.Gauges.MinorTicks minorTicks = new Visifire.Gauges.MinorTicks();
                        minorTicks.Visibility = System.Windows.Visibility.Hidden;
                        ctlGauge.LinearScales[0].MinorTicks = minorTicks;

                        Visifire.Gauges.MajorTicks majorTicks = new Visifire.Gauges.MajorTicks();
                        majorTicks.Visibility = System.Windows.Visibility.Hidden;
                        ctlGauge.LinearScales[0].MajorTicks = majorTicks;
                    }

                    if (Xinterval.HasValue)
                    {
                        if (Xinterval.Value != 0)
                            ctlGauge.LinearScales[0].Interval = Xinterval.Value;
                    }
                    if (XMinimum.HasValue)
                    {
                        ctlGauge.LinearScales[0].Minimum = XMinimum.Value;
                    }
                    if (XMaximum.HasValue)
                    {
                        ctlGauge.LinearScales[0].Maximum = XMaximum.Value;
                    }

                }
            }

            if (ctlGauge.CircularScales != null && ctlGauge.CircularScales.Count > 0)
            {

                if ((bool)XIsScaleVisible)
                {
                    Visifire.Gauges.ScaleLabels scaleLabels = new Visifire.Gauges.ScaleLabels();
                    scaleLabels.Visibility = System.Windows.Visibility.Visible;
                    scaleLabels.FontColor = XForeground.Brush;
                    scaleLabels.FontSize = (double)XScaleFontSize;
                    if (!string.IsNullOrEmpty(XScaleLabelPosition))
                    {
                        if (XScaleLabelPosition == Visifire.Gauges.PlacementTypes.Outside.ToString())
                        {
                            scaleLabels.Placement = Visifire.Gauges.PlacementTypes.Outside;
                        }
                        else if (XScaleLabelPosition == Visifire.Gauges.PlacementTypes.Inside.ToString())
                        {
                            scaleLabels.Placement = Visifire.Gauges.PlacementTypes.Inside;
                        }
                        else if (XScaleLabelPosition == Visifire.Gauges.PlacementTypes.Center.ToString())
                        {
                            scaleLabels.Placement = Visifire.Gauges.PlacementTypes.Center;
                        }
                    }

                    ctlGauge.CircularScales[0].ScaleLabels = scaleLabels;

                    Visifire.Gauges.MinorTicks minorTicks = new Visifire.Gauges.MinorTicks();
                    minorTicks.Visibility = System.Windows.Visibility.Visible;
                    ctlGauge.CircularScales[0].MinorTicks = minorTicks;

                    Visifire.Gauges.MajorTicks majorTicks = new Visifire.Gauges.MajorTicks();
                    majorTicks.Visibility = System.Windows.Visibility.Visible;
                    ctlGauge.CircularScales[0].MajorTicks = majorTicks;
                }
                else
                {
                    Visifire.Gauges.ScaleLabels scaleLabels = new Visifire.Gauges.ScaleLabels();
                    scaleLabels.Visibility = System.Windows.Visibility.Hidden;
                    ctlGauge.CircularScales[0].ScaleLabels = scaleLabels;

                    Visifire.Gauges.MinorTicks minorTicks = new Visifire.Gauges.MinorTicks();
                    minorTicks.Visibility = System.Windows.Visibility.Hidden;
                    ctlGauge.CircularScales[0].MinorTicks = minorTicks;

                    Visifire.Gauges.MajorTicks majorTicks = new Visifire.Gauges.MajorTicks();
                    majorTicks.Visibility = System.Windows.Visibility.Hidden;
                    ctlGauge.CircularScales[0].MajorTicks = majorTicks;
                }

                if (Xinterval.HasValue)
                {
                    if (Xinterval.Value != 0)
                        ctlGauge.CircularScales[0].Interval = Xinterval.Value;
                }
                if (XMinimum.HasValue)
                {
                    ctlGauge.CircularScales[0].Minimum = XMinimum.Value;
                }
                if (XMaximum.HasValue)
                {
                    ctlGauge.CircularScales[0].Maximum = XMaximum.Value;
                }
            }

            if (XDataRanges != null && XDataRanges.Count > 0)
            {
                foreach (DataRange dataRange in XDataRanges)
                {
                    Visifire.Gauges.Range range = new Visifire.Gauges.Range();
                    range.StartValue = dataRange.StartValue;
                    range.EndValue = dataRange.EndValue;
                    range.StartWidth = dataRange.StartWidth;
                    range.EndWidth = dataRange.EndWidth;
                    range.Background = dataRange.Background.Brush;
                    range.BorderBrush = dataRange.BorderBrush.Brush;
                    range.BorderThickness = dataRange.BorderThickness;
                    range.Placement = Visifire.Gauges.PlacementTypes.Center;
                    ctlGauge.Ranges.Add(range);
                }
            }

            if (ctlGauge.Indicators != null && ctlGauge.Indicators.Count > 0)
            {
                if (XFillBarBackground != null)
                {
                    ctlGauge.Indicators[0].Background = XFillBarBackground;
                }

                if (XFillBarBorderBrush != null)
                {
                    ctlGauge.Indicators[0].BorderBrush = XFillBarBorderBrush;
                }

                if (XFillBarBorderThickness != null )
                {
                    ctlGauge.Indicators[0].BorderThickness = XFillBarBorderThickness;
                }
                if (XIsShowThreshold != null && (bool)XIsShowThreshold)
                {
                    if (XThreshold != null && XThreshold > 0)
                    {
                        Visifire.Gauges.MarkerIndicator xThresholdMarkerIndicator = new Visifire.Gauges.MarkerIndicator();
                        xThresholdMarkerIndicator.Value = (double)XThreshold;
                        xThresholdMarkerIndicator.MarkerShape = Visifire.Gauges.Shapes.Line;
                        xThresholdMarkerIndicator.IndicatorLength = 0.5;
                        xThresholdMarkerIndicator.IndicatorWidth = 0.5;
                        xThresholdMarkerIndicator.BorderBrush = new SolidColorBrush(Colors.Red);
                        ctlGauge.Indicators.Add(xThresholdMarkerIndicator);

                    }
                }
                
            }
        }

        #endregion

        /// <summary>
        /// 获得仪表盘
        /// </summary>
        /// <returns></returns>
        protected abstract Visifire.Gauges.Gauge GetVisifireGauge();
    }
}
